#include "parser.h"

Parser::Parser(Token_stream &ts) : ts(ts)
{
}

double Parser::expression()
{
    double left = term();
    Token op = ts.get();
    while (op.kind == '+' || op.kind == '-')
    {
        if (op.kind == '+')
        {
            left += term();
        }
        else
        {
            left -= term();
        }
        op = ts.get();
    }
    ts.putback(op);
    return left;
}

double Parser::term()
{
    double left = primary();
    Token op = ts.get();
    while (op.kind == '*' || op.kind == '/')
    {
        if (op.kind == '*')
        {
            left *= primary();
        }
        else
        {
            double d = primary();
            if (d == 0)
            {
                throw Parser_error("divided by zero");
            }
            left /= d;
        }
        op = ts.get();
    }
    ts.putback(op);
    return left;
}

double Parser::primary()
{
    Token t = ts.get();
    if (t.kind == '(')
    {
        double d = expression();
        if (ts.get().kind != ')')
        {
            throw Parser_error("')' expected");
        }
        return d;
    }
    else if (t.kind == number)
    {
        return t.value;
    }
    else
    {
        throw Parser_error("primary expected");
    }
}